using System;
using System.Text;
using System.Data;

namespace Antu.Core.Ajax
{
    /// <summary>
    /// Provides methods to serialize and deserialize a Exception object.
    /// </summary>
    public class ExceptionConverter : AbstractJavascriptConverter
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ExceptionConverter"/> class.
        /// </summary>
        public ExceptionConverter()
            : base()
        {
            allowInheritance = true;

            serializabletypeslist = new Type[] {
				typeof(Exception),
				typeof(NotImplementedException),
				typeof(NotSupportedException),
				typeof(NullReferenceException),
				typeof(System.Security.SecurityException)
			};
        }

        /// <summary>
        /// Converts a .NET object into a JSON string.
        /// </summary>
        /// <param name="o">The object to convert.</param>
        /// <returns>Returns a JSON string.</returns>
        public override string Serialize(object o)
        {
            StringBuilder sb = new StringBuilder();
            Serialize(o, sb);
            return sb.ToString();
        }

        /// <summary>
        /// Serializes the specified o.
        /// </summary>
        /// <param name="o">The o.</param>
        /// <param name="sb">The sb.</param>
        public override void Serialize(object o, StringBuilder sb)
        {
            Exception ex = (Exception)o;

            // The following line is NON-JSON format, it is used to 
            // return null to res.value and have an additional property res.error
            // in the object the callback JavaScript method will get.

            sb.Append("{\"message\":");
            JavaScriptUtil.QuoteString(ex.Message, sb);
            sb.Append(",\"type\":");
            JavaScriptUtil.QuoteString(o.GetType().FullName, sb);
            //if (AjaxUtility.Settings.DebugEnabled)
            //{
            //    sb.Append(",\"stack\":");
            //    JavaScriptUtil.QuoteString(ex.StackTrace, sb);

            //    if (ex.TargetSite != null)
            //    {
            //        sb.Append(",\"targetSite\":");
            //        JavaScriptUtil.QuoteString(ex.TargetSite.ToString(), sb);
            //    }

            //    sb.Append(",\"source\":");
            //    JavaScriptUtil.QuoteString(ex.Source, sb);
            //}
            sb.Append("}");
        }

        /// <summary>
        /// Tries the serialize value.
        /// </summary>
        /// <param name="o">The o.</param>
        /// <param name="t">The t.</param>
        /// <param name="sb">The sb.</param>
        /// <returns></returns>
        public override bool TrySerializeValue(object o, Type t, StringBuilder sb)
        {
            Exception ex = o as Exception;
            if (ex != null)
            {
                this.Serialize(ex, sb);
                return true;
            }

            return base.TrySerializeValue(o, t, sb);
        }
    }
}
